﻿using System;
using System.Collections.Generic;
using System.Text;
using log4net;
using EnCor.ObjectBuilder;

namespace EnCor.Logging
{
    [AssembleConfig(typeof(Log4netAdaptorConfig))]
    public class Log4netAdaptor : Logger
    {
        log4net.ILog _log4netLog = null;
        public Log4netAdaptor(string log4netLoggerName)
        {
            log4net.Config.XmlConfigurator.Configure();
            _log4netLog = log4net.LogManager.GetLogger(log4netLoggerName);
        }
        #region ILoggerAdapter Members

        public void Write(LogEntry logEntry)
        {
            log4net.Core.LoggingEventData data = WrapLoggingData(logEntry);
            log4net.Core.LoggingEvent logEvent = new log4net.Core.LoggingEvent(data);
            _log4netLog.Logger.Log(logEvent);
            
        }

        private log4net.Core.LoggingEventData WrapLoggingData(LogEntry logEntry)
        {
            log4net.Core.LoggingEventData data = new log4net.Core.LoggingEventData();
            data.Domain = logEntry.AppDomainName;
            data.ExceptionString = logEntry.Exception == null ? null : logEntry.Exception.ToString();
            data.Identity = Security.SecurityContext.Current.Identity.UserId;
            if (logEntry.Level == LogLevel.Debug)
            {
                data.Level = log4net.Core.Level.Debug;
            }
            else if (logEntry.Level == LogLevel.Error)
            {
                data.Level = log4net.Core.Level.Error;
            }
            else if (logEntry.Level == LogLevel.Fatal)
            {
                data.Level = log4net.Core.Level.Fatal;
            }
            else if (logEntry.Level == LogLevel.Information)
            {
                data.Level = log4net.Core.Level.Info;
            }
            else if (logEntry.Level == LogLevel.Warning)
            {
                data.Level = log4net.Core.Level.Warn;
            }
            else
            {
                throw new EnCorException(string.Format("Cannot process the level :{0}", logEntry.Level));
            }

            data.LoggerName = logEntry.LoggerName;
            data.Message = logEntry.Message;
            foreach (string key in logEntry.ExtendProperties.Keys)
            {
                data.Properties[key] = logEntry.ExtendProperties[key];
            }
            data.ThreadName = logEntry.ThreadName;
            data.TimeStamp = logEntry.TimeStamp;
            data.UserName = Security.SecurityContext.Current.Identity.Name;
            return data;

        }

        #endregion
        public override void Log(LogEntry logEntry)
        {
            log4net.Core.LoggingEventData data = WrapLoggingData(logEntry);
            log4net.Core.LoggingEvent logEvent = new log4net.Core.LoggingEvent(data);
            _log4netLog.Logger.Log(logEvent);
        }    
    
    }
}
